<html>

<head>
    <title>文本转excel</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="./bootstrap/css/bootstrap.css" />
    <link rel="stylesheet" type="text/css" href="./bootstrap/css/main.css" />
    <link rel="stylesheet" type="text/css" href="./static/css/dialog.css" />
    <style>
        .form-inline .form-control-sm,
        .form-inline .btn {
            margin-right: 3px;
        }

        .btn-wrap {
            position: fixed;
            bottom: 0;
            padding: 10px 0;
            width: 100%;
            display: none;
            background: #fff;
        }

        .main {
            padding-bottom: 50px;
        }

        .mask {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            top: 0;
            background: rgba(0, 0, 0, 0.6);
            color: #fff;
            display: none;
            z-index: 100;
        }

        .process-wrap {
            position: relative;
            width: 100%;
            height: 100%;
        }

        .process {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        pre {
            margin: 0;
            white-space: pre-wrap;
        }
    </style>
    <script src="./bootstrap/js/jquery-2.1.4.js"></script>
    <script src="./static/js/dialog.js"></script>
    <script src="./static/js/xlsx.core.min.js"></script>
</head>

<body>
    <div class="main">
        <div class="form-inline" style="margin: 10px auto">
            <input type="file" id="file" style="display:none;"/>
            <input id="btn_list" type="button" class="btn btn-outline-dark btn-sm" value="选择要处理的txt文件" />
            <input id="btn_change_charset" type="button" class="btn btn-outline-dark btn-sm" value="有乱码" />
            <input id="btn_export" type="button" class="btn btn-outline-dark btn-sm" value="确认导出" />

            <pre id="file_content">

            </pre>
            <script>
                $(function() {
                    let $file = $('#file');
                    let $table = $('#table');
                    let $file_info = $('#file_info');
                    let $btn_wrap = $('.btn-wrap');
                    let $file_info_confirm = $('#file_info_confirm');
                    let $mask = $('.mask');
                    let $process = $('.process');
                    let $file_content = $('#file_content');
                    $('#btn_change_charset').on('click', function() {
                        charset = charset == 'gb2312'? 'utf-8': 'gb2312';
                        read();
                    });
                    $('#btn_export').on('click', function() {
                        exportContent();
                    })
                    $file_info.on('click', function() {
                        $btn_wrap.hide();
                        $file_info.html('');
                        $table.html('');
                    });
                    $file_info_confirm.on('click', function() {
                        $mask.show();
                        let arr = [];
                        $('table tr').each((i, v) => {
                            if (i > 0) {
                                let arr_val = [];
                                $(v).find('td').each((i, v) => {
                                    arr_val.push($(v).text());
                                });
                                arr.push({
                                    id: $(v).attr('id'),
                                    xuhao: $(v).data('xuhao'),
                                    data: arr_val
                                });
                            }
                        });
                        
                        let len_total = arr.length;
                        let len_down = 0;
                        let len_success = 0;
                        function run() {
                            let html = len_down + '/' +len_total+' 成功'+len_success+'条';
                            $process.html(html);
                            let item = arr.shift();
                            if (item) {
                                $.post('', {
                                    from: 'ajax',
                                    xuhao: item.xuhao,
                                    data: item.data
                                }, function(res) {
                                    len_down ++;
                                    try {
                                        res = JSON.parse(res);
                                    }catch(e){}
                                    if (res.success) {
                                        len_success++;
                                    }
                                    $('#'+item.id).remove();

                                    run();
                                })
                            } else {
                                $file_info.click();
                                setTimeout(function() {
                                    $mask.hide();
                                    alertMsg('成功导入'+len_success+'条！');
                                }, 1000);
                            }
                        }
                        run();
                    })
                    $('#btn_list').on('click', function() {
                        $file.click();
                    })
                    let reg_ti = /\d{1,4}\.(.+)(?=[ABCD]\.)/;
                    let file_content = '';
                    let charset = 'gb2312';

                    function exportContent() {
                        let index_arr = [];
                        let lines = file_content.split(/[\r\n]+/).filter(v => {
                            return v && v.trim();
                        });
                        lines.forEach((v, i) => {
                            if (/^\s*\d+\./.test(v)) {
                                index_arr.push(i);
                            }
                        });
                        if (lines.length == 0) {
                            return alert('当前没有要导出内容');
                        }
                        let ti_list = [];
                        let index_start = index_arr.shift();
                        let index_end = 0;
                        while ((index_end = index_arr.shift()) > 0) {
                            ti_list.push(lines.slice(index_start, index_end));
                            index_start = index_end;
                        }
                        if (index_start < lines.length) {
                            ti_list.push(lines.slice(index_start, lines.length));
                        }

                        window.ti_list = ti_list;
                        ti_list.forEach((v, i) => {
                            let result = /^\s*\d+\.(?<tigan>[\S\s]+?)(?<xuanxiang>([ABCDEF]\.[^ABCDEF]+)+)【答案】(?<daan>.*)\s*【解析】(?<jiexi>.*)/.exec(v.join(''));

                            if (!result) {
                                return
                            }
                            let g = result.groups;
                            let m_ti = /(【([单多]选题?)】)?(.+)/.exec(g.tigan);
                            let ti = m_ti[3];
                            let tixing = m_ti[2] || '';
                            let daan = g.daan
                            let jiexi = g.jiexi

                            let reg_xuanxiang = /[ABCDEF]\./;
                            let xuanxiang = g.xuanxiang.split(reg_xuanxiang).filter(v => { return v });

                            daan = daan.replace(/[,，]/g, '').split('').filter(v => { return v && v.trim() }).join(',');  // 分割多选
                            ti_list[i] = {
                                ti, tixing, daan, jiexi, xuanxiang
                            };
                        })

                        let sheetName = 'sheet1';
                        var workbook = {
                            SheetNames: [sheetName],
                            Sheets: {}
                        };
                        var sheet = {
                            'A1': { v: '题型' },
                            'B1': { v: '题干内容' },
                            'C1': { v: '解析' },
                            'D1': { v: '难度' },
                            'E1': { v: '答案' },
                            'F1': { v: '选项A' },
                            'G1': { v: '选项B' },
                            'H1': { v: '选项C' },
                            'I1': { v: '选项D' },
                        };
                        sheet['!ref'] = 'A1:M' + (ti_list.length + 1);
                        ti_list.forEach((v, i) => {
                            let row = i + 2;
                            sheet['A' + row] = { v: v.tixing };
                            sheet['B' + row] = { v: v.ti };
                            sheet['C' + row] = { v: v.jiexi };
                            sheet['D' + row] = {
                                v: ''
                            };
                            sheet['E' + row] = {
                                v: v.daan
                            };

                            (v.xuanxiang || []).forEach((vv, ii) => {
                                sheet[String.fromCharCode(70 + ii) + row] = {
                                    v: vv
                                };
                            })
                        });
                        workbook.Sheets[sheetName] = sheet;
                        // 生成excel的配置项
                        var wopts = {
                            bookType: 'xlsx', // 要生成的文件类型
                            bookSST: false, // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
                            type: 'binary'
                        };
                        console.log(workbook)
                        var wbout = XLSX.write(workbook, wopts);
                        var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
                        // 字符串转ArrayBuffer
                        function s2ab(s) {
                            var buf = new ArrayBuffer(s.length);
                            var view = new Uint8Array(buf);
                            for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
                            return buf;
                        }
                        let url = URL.createObjectURL(blob); // 创建blob地址
                        var aLink = document.createElement('a');
                        aLink.href = url;
                        aLink.download = 'result.xlsx'; // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
                        var event;
                        if (window.MouseEvent) event = new MouseEvent('click');
                        else {
                            event = document.createEvent('MouseEvents');
                            event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                        }
                        aLink.dispatchEvent(event);

                        alert('文件已成功下载');
                    }

                    let file_current;

                    function read() {
                        if (!file_current) {
                            return alert('请先选择要处理的文件')
                        }
                        return new Promise(resolve => {
                            var reader = new FileReader();
                            reader.onload = function (e) {
                                try {
                                    var data = e.target.result;
                                    $file_content.text(data);
                                    file_content = data;


                                    resolve();
                                } catch (e) {
                                    resolve(e)
                                }
                            };
                            reader.readAsText(file_current, charset);
                        })
                    }
                    $file.on('change', function(e) {
                        let files = e.target.files;
                        if (files.length == 0) {
                            return;
                        }
                        let file = files[0];
                        file_current = file;
                        if(!/\.txt$/g.test(file.name)) {
                            alertMsg('仅支持读取txt格式！');
                            return;
                        }
                        $file.val('');

                        read();
                    });

                });
            </script>
        </div>

        <div id="table">

        </div>
    </div>
</body>

</html>